package wntm;

//import org.deeplearning4j.models.embeddings.loader.WordVectorSerializer;
//import org.deeplearning4j.models.embeddings.wordvectors.WordVectors;



import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Prepare input data for Word Network Topic Model(WNTM)
 *
 * @author Yuan Zuo
 */
public class PrepareInput_w2v_similarity {

//    // Store original documents, store word IDs to reduce memory consumption
//    private List<List<Integer>> docs = new ArrayList<List<Integer>>();
//
//    // Dictionary: word map to its ID and ID map to word
//    private Map<String, Integer> w2i = new HashMap<String, Integer>();
//    private Map<Integer, String> i2w = new HashMap<Integer, String>();
//
//    // Node map to its adjacent list
//    private Map<Integer, Map<Integer, Double>> n2e = new HashMap<>();
//
//    // Please refer to paper for the definitions of a node's degree and activity
//    // Nodes' degrees: node(word id) map to its degree
//    private Map<Integer, Double> n2d = new HashMap<>();
//
//    // Nodes' activity: node(word id) map to its activity
//    private Map<Integer, Integer> n2a = new HashMap<>();
//    private WordVectors w2vModel = null;
//
//    public static void main(String[] args) {
//        PrepareInput_w2v_similarity preIput = new PrepareInput_w2v_similarity();
//        String root = "data/news/wntm_w2v/";
//        String orgFile = root + "news.data";
//        String outDir = root;
//        String pseName = "news";
//        int windowSize = 10;
//        preIput.prepareInput(orgFile, outDir + pseName, windowSize, "G:\\我的本地文件\\数据\\w2v_pretrain\\wiki.en.text.vector");
//    }
//
//    private BufferedReader getReader(String path, String charset) {
//        BufferedReader reader = null;
//        try {
//            reader = new BufferedReader(new InputStreamReader(
//                    new FileInputStream(path), charset));
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//        return reader;
//    }
//
//    private BufferedWriter getWriter(String path, String charset) {
//        BufferedWriter writer = null;
//        try {
//            writer = new BufferedWriter(new OutputStreamWriter(
//                    new FileOutputStream(path), charset));
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//        return writer;
//    }
//
//    private void loadTxt(String org) {
//        BufferedReader reader = getReader(org, "utf-8");
//
//        String line;
//
//        System.out.println("Loading txt file ...");
//
//        try {
//            line = reader.readLine();
//            while (line != null) {
//                List<Integer> doc = new ArrayList<Integer>();
//                String[] tokens = line.trim().split("\\s+");
//
//                for (String token : tokens) {
//                    if (!w2i.containsKey(token)) {
//                        w2i.put(token, w2i.size());
//                        i2w.put(w2i.get(token), token);
//                    }
//                    doc.add(w2i.get(token));
//                }
//
//                docs.add(doc);
//                line = reader.readLine();
//            }
//            reader.close();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//    }
//
//    private Double sumOfAdjacentWeights(Map<Integer, Double> map) {
//        Double sum = 0.0;
//        for (int key : map.keySet())
//            sum += map.get(key);
//        return sum;
//    }
//
//    /**
//     * @param ws: Sliding window size
//     */
//    private void buildWordNet(int ws) {
//        System.out.println("Building Word Network ...");
//        int D = docs.size();
//        int prePercent = 0;
//        for (int d = 0; d != D; d++) {
//
//            if (d % 1000 == 0) {
//                int percent = (int) Math.ceil(100 * ((double) d / (double) D));
//                if (prePercent != percent) {
//                    prePercent = percent;
//                    System.out.println(String.format("%d%%", percent));
//                }
//            }
//
//            int N = docs.get(d).size();
//            int totalSlides = N <= ws ? 1 : (N - ws + 1);
//
//            for (int s = 0; s != totalSlides; s++) {
//                int toIndex = N <= ws ? N : (s + ws);
//                List<Integer> window = docs.get(d).subList(s, toIndex);
//                for (Integer node1 : window) {
//                    if (!n2e.containsKey(node1)) {
//                        Map<Integer, Double> n1Edges = new HashMap<>();
//                        n2e.put(node1, n1Edges);
//                    }
//                    for (Integer node2 : window) {
//                        if (
//                                node1.compareTo(node2) != 0
//                                        && w2vModel.hasWord(i2w.get(node1))
//                                        && w2vModel.hasWord(i2w.get(node2))
//                                        && w2vModel.similarity(i2w.get(node1), i2w.get(node2)) > 0
//                                ) {
//                            // Update n2e
//                            Map<Integer, Double> n1Edges = n2e.get(node1);
//                            if (n1Edges.containsKey(node2))
//                                n1Edges.put(node2, n1Edges.get(node2) + 1);
//                            else
//                                n1Edges.put(node2, 1.0);
//
//                        }
//                    }
//                }
//            }
//        }
//
//        // Compute n2d and n2a
//        for (int node : n2e.keySet()) {
//            Double degree = sumOfAdjacentWeights(n2e.get(node));
//            int activity = (int) Math.ceil(degree
//                    / (double) n2e.get(node).size());
//            n2d.put(node, degree);
//            n2a.put(node, activity);
//        }
//    }
//
//    private void networkReweight() {
//
//        System.out.println("Network Re-weighting ...");
//
//        for (int node1 : n2e.keySet()) {
//            Map<Integer, Double> n1Edges = n2e.get(node1);
//            for (int node2 : n2e.get(node1).keySet()) {
//                int tnode = n2d.get(node1) <= n2d.get(node2) ? node1 : node2;
//                int activity = n2a.get(tnode);
//                n1Edges.put(node2, Math.ceil(n1Edges.get(node2) / (double) activity));
//            }
//            n2e.put(node1, n1Edges);
//        }
//    }
//
//    private void writeOutput(String pseudoName) {
//
//        System.out.println("Writeing output ...");
//
//        BufferedWriter wWriter = getWriter(pseudoName + ".words", "utf-8");
//        BufferedWriter aWriter = getWriter(pseudoName + ".adjacent", "utf-8");
//
//        try {
//            //aWriter.append(n2e.size()+"\n");
//
//            for (int node1 : n2e.keySet()) {
//                Map<Integer, Double> n1Edges = n2e.get(node1);
//                wWriter.append(i2w.get(node1) + "\n");
//                aWriter.append(i2w.get(node1) + " ");
//
//                for (int node2 : n1Edges.keySet()) {
//                    for (int i = 0; i < n1Edges.get(node2); i++) {
//                        aWriter.append(i2w.get(node2) + " ");
//                    }
//                }
//                aWriter.append("\n");
//            }
//            wWriter.flush();
//            wWriter.close();
//            aWriter.flush();
//            aWriter.close();
//        } catch (IOException e) {
//            // TODO Auto-generated catch block
//            e.printStackTrace();
//        }
//    }
//
//    /**
//     * Build word network from original corpus and re-weighting the network, then output pseudo documents.
//     *
//     * @param org:        Original corpus
//     * @param pseudoName: Pseudo documents i.e. input for WNTM
//     */
//    public void prepareInput(String org, String pseudoName, int ws, String w2vPath) {
//        loadTxt(org);
//        try {
//            this.w2vModel = WordVectorSerializer.loadTxtVectors(new File(w2vPath));
//        } catch (FileNotFoundException e) {
//            e.printStackTrace();
//        }
//        buildWordNet(ws);
//        networkReweight();
//        writeOutput(pseudoName);
//    }
}
